/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef __COM_UTIL_INPROC_SERVER_H__
#define __COM_UTIL_INPROC_SERVER_H__

#include <unknwn.h>
#include "lock_counter.h"
#include <string>
#include <list>

//IMPORTANT NOTE:
//developer who uses libcom to create inproc server,
//must implement two functions from namespace libcom:
//void libcom::register_class_factories(const String & dll_path);
//void libcom::create_class_factories(InprocServer * server);
//The "register_class factories" function unifies class factories registration,
//while the "create class_factories" function unifies creation of class factories for all COM objects.
//To implement these functions is very simple. Given COM coclasses MyCoclass1, ..., MyCoclassN,
//implementation will be the following:
/*
#include <libcom/inproc_server.h>

namespace libcom
{

void register_class_factories(const String & server_path)
{
	InprocFactory<MyCoclass1>::Register(server_path);
	//...
	InprocFactory<MyCoclassN>::Register(server_path);
}

void create_class_factories(InprocServer * server)
{
	server->add_class_factory(CLSID_MyCoclass1, new InprocFactory<MyCoclass1>(server));
	//...
	server->add_class_factory(CLSID_MyCoclassN, new InprocFactory<MyCoclassN>(server));
}

}//namespace libcom
*/

namespace libcom
{

class InprocServer;

void register_class_factories(const std::string & dll_path);
void create_class_factories(InprocServer * server);

class InprocServer : public LockCounter
{
public:
	InprocServer();
	~InprocServer();

	void add_class_factory(const GUID & class_id, IClassFactory * factory)
	{
		factory->AddRef();
		factories.push_back(std::make_pair(class_id, factory));
	}
	
	long get_factory(const GUID & coclass, const GUID & factory_iid, void ** interface_ptr);
	
	static bool register_typelib_resource();
	
	static std::string server_dll_path;	

	static BOOL DllMain(HINSTANCE module_handle, DWORD reason);

private:
	typedef std::list<std::pair<GUID, IClassFactory*> > Factories;	//GUID is coclass uid to be created by the factory
	Factories factories;
};

}//end of namespace

#endif

